﻿using System;
using System.Collections.Generic;
using System.Transactions;
using System.Linq;
using Hxsoft.AppV1;

namespace Hxsoft.AppV1.Module
{
	public partial class Role : ICreator { }




	/// <summary>
	/// Roles 类。
	/// </summary>
	public static partial class Roles
	{
		public const string INFO_TYPE = "Role";


		/// <summary>
		/// 管理员角色名。
		/// </summary>
		public const string AdministratorRoleName = "Administrators";

		/// <summary>
		/// 所有人角色名。
		/// </summary>
		public const string EveryoneRoleName = "Everyone";

		/// <summary>
		/// 所有者角色名。
		/// </summary>
		public const string OwnerRoleName = "Owner";

		/// <summary>
		/// 创建者角色名。
		/// </summary>
		public const string CreatorRoleName = "Creator";

		/// <summary>
		/// 用户角色。
		/// </summary>
		public const string UserRoleName = "User";



		#region RoleHasProperty
		/// <summary>
		/// 验证角色属性是否拥有指定的属性。
		/// </summary>
		/// <param name="roleProperty">角色的属性。</param>
		/// <param name="propertyCode">进行验证的属性码。</param>
		/// <returns>布尔值表示角色属性是否拥有指定的属性。</returns>
		public static bool RolePropertyHasProperty(int? roleProperty, RolePropertyCode propertyCode)
		{
			if (roleProperty == null) return false;
			return (roleProperty & (int)propertyCode) == (int)propertyCode ? true : false;
		}




		public static bool RoleHasProperty(int? siteId, string roleName, RolePropertyCode propertyCode)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.Roles.RoleHasProperty(siteId, roleName, propertyCode);
		}

		/// <summary>
		/// 验证角色是否拥有指定的属性。
		/// </summary>
		/// <param name="roleName">角色名。</param>
		/// <param name="propertyCode">进行验证的属性码。</param>
		/// <returns>布尔值表示角色是否拥有指定的属性。</returns>
		public static bool RoleHasProperty(this System.Data.Linq.Table<Role> o, int? siteId, string roleName, RolePropertyCode propertyCode)
		{
			Role role = o.GetItem(siteId, roleName);
			if (role == null)
				throw new ObjectNotExistsException(Res.Roles_NotExistsRole);

			return RolePropertyHasProperty(role.PropertyCode, propertyCode);
		}

		public static bool RoleHasProperty(Guid roleId, RolePropertyCode propertyCode)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.Roles.RoleHasProperty(roleId, propertyCode);
		}



		/// <summary>
		/// 验证角色是否拥有指定的属性。
		/// </summary>
		/// <param name="roleId">角色标识。</param>
		/// <param name="propertyCode">进行验证的属性码。</param>
		/// <returns>布尔值表示角色是否拥有指定的属性。</returns>
		public static bool RoleHasProperty(this System.Data.Linq.Table<Role> o, Guid roleId, RolePropertyCode propertyCode)
		{
			Role role = o.GetItem(roleId);
			if (role == null)
				throw new ObjectNotExistsException(Res.Roles_NotExistsRole);

			return RolePropertyHasProperty(role.PropertyCode, propertyCode);
		}
		#endregion



		#region IsUserInRole
		public static bool IsUserInRole(string username, int? siteId, string roleName)
		{
			return UsersInRoles.Exists(username, siteId, roleName);
		}
		#endregion



		#region GetRolesForUser
		public static Guid[] GetRolesForUser(string username)
		{
			return UsersInRoles.GetRolesForUser(username);
		}
		#endregion



		#region GetUsersInRole
		public static string[] GetUsersInRole(int? siteId, string roleName)
		{
			return UsersInRoles.GetUsersInRole(siteId, roleName);
		}

		public static string[] GetUsersInRole(Guid roleId)
		{
			return UsersInRoles.GetUsersInRole(roleId);
		}
		#endregion



		#region Exists
		/// <summary>
		/// 通过角色名验证指定的角色是否存在。
		/// </summary>
		/// <param name="o">角色集合。</param>
		/// <param name="siteId">角色所属的站点。</param>
		/// <param name="roleName">角色名。</param>
		/// <returns>布尔值代表角色是否存在。</returns>
		public static bool Exists(this System.Data.Linq.Table<Role> o, int? siteId, string roleName)
		{
			if(siteId.HasValue)
				return o.Any(p => p.SiteId == siteId.Value && p.RoleName == roleName);
			return o.Any(p => p.SiteId == null && p.RoleName == roleName);
		}
		#endregion



		#region GetIdentifier
		/// <summary>
		/// 根据角色的名称获取角色标识。
		/// </summary>
		/// <param name="o">类别的集合。</param>
		/// <param name="siteId">角色所属的站点。</param>
		/// <param name="roleName">角色的名称。</param>
		/// <returns>角色的标识。</returns>
		public static Guid? GetIdentifier(this System.Data.Linq.Table<Role> o, int? siteId, string roleName)
		{
			IQueryable<Guid?> q;
			if(siteId.HasValue)
				q = from r in o
					where r.SiteId == siteId.Value && r.RoleName == roleName
					select (Guid?)r.RoleId;
			else
				q = from r in o
					where r.SiteId == null && r.RoleName == roleName
					select (Guid?)r.RoleId;
			return q.SingleOrDefault();
		}
		#endregion



		#region GetItem
		/// <summary>
		/// 通过角色标识获取角色信息。
		/// </summary>
		/// <param name="o">角色集合。</param>
		/// <param name="id">角色标识。</param>
		/// <returns>指定的角色信息。</returns>
		public static Role GetItem(this System.Data.Linq.Table<Role> o, Guid id)
		{
			return o.SingleOrDefault(r => r.RoleId == id);
		}

		public static Role GetItem(Guid id)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.Roles.GetItem(id);
		}

		

		/// <summary>
		/// 通过角色名获取角色信息。
		/// </summary>
		/// <param name="o">角色集合。</param>
		/// <param name="roleName">角色名。</param>
		/// <returns>指定的角色信息。</returns>
		public static Role GetItem(this System.Data.Linq.Table<Role> o, int? siteId, string roleName)
		{
			if(siteId.HasValue)
				return o.SingleOrDefault(r => r.SiteId == siteId.Value && r.RoleName == roleName);
			return o.SingleOrDefault(r => r.SiteId == null && r.RoleName == roleName);
		}

		public static Role GetItem(int? siteId, string roleName)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.Roles.GetItem(siteId, roleName);
		}
		#endregion

		/// <summary>
		/// 角色特性码。
		/// </summary>
		[Flags]
		public enum RolePropertyCode
		{
			DisallowDelete = 1,
			DisallowUserAccredit = 2,
			DisallowRoleAccredit = 4
		}
	}



	/// <summary>
	/// Roles 类操作部分。
	/// </summary>
	public static partial class Roles
	{
		#region RegisterAdministratorRole
		/// <summary>
		/// 注册管理员角色。
		/// </summary>
		internal static void RegisterAdministratorRole()
		{
			Role role = new Role();

			role.RoleName = AdministratorRoleName;
			role.Description = "系统管理员角色，具有系统最高管理权限。";
			role.PropertyCode = (int)(RolePropertyCode.DisallowDelete | RolePropertyCode.DisallowRoleAccredit);

			RegisterRole(role);
		}
		#endregion



		#region RegisterRole
		internal static void RegisterRole(Role role)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			if (!dc.Roles.Exists(role.SiteId, role.RoleName))
			{
				_CreateRole(dc, role);
			}
		}
		#endregion



		#region CreateRole
		/// <summary>
		/// 创建角色。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="createdRole">创建的角色信息。</param>
		/// <returns>创建的角色信息。</returns>
		private static Role _CreateRole(GenericModuleDataContext dc, Role createdRole)
		{
			Role role = createdRole.ToNewEntity<Role>();
			role.RoleId = Guid.NewGuid();
			role.CreatorId = Users.CurrentUserId;
			role.CreationDate = DateTime.Now;

			dc.Roles.InsertOnSubmit(role);
			dc.SubmitChanges();

			return createdRole.FillByEntity(role);
		}

		/// <summary>
		/// 创建角色。
		/// </summary>
		/// <param name="createdRole">要创建的角色信息。</param>
		internal static Role _CreateRole(Role createdRole)
		{
			return _CreateRole(new GenericModuleDataContext(), createdRole);
		}

		/// <summary>
		/// 创建角色。
		/// </summary>
		/// <param name="createdRole">要创建的角色信息。</param>
		public static Role CreateRole(Role createdRole)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			createdRole.CreatorId = Users.CurrentUserId;
			createdRole.CreationDate = DateTime.Now;

			GetCreateRight(dc, createdRole, true);	// 权限验证

			var role = _CreateRole(dc, createdRole);

			// 记录日志
			Logs.Insert(dc, ResourceId, (int)PermissionCode.Create, INFO_TYPE, role.RoleId.ToString(), PermissionCode.Create.ToString(), role.RoleName);

			return role;
		}
		#endregion



		#region AddUsersToRole
		internal static void _AddUserToRole(string username, int? siteId, string roleName)
		{
			_AddUsersToRole(new string[] { username }, siteId, roleName);
		}

		internal static void _AddUsersToRole(string[] usernames, int? siteId, string roleName)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			Role role = dc.Roles.GetItem(siteId, roleName);
			if (role == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			AddUsersToRole(dc, usernames, role);
		}

		private static void AddUsersToRole(GenericModuleDataContext dc, string[] usernames, Role role)
		{
			if (Roles.RolePropertyHasProperty(role.PropertyCode, RolePropertyCode.DisallowUserAccredit))
				throw new OperationException(Res.Roles_DisallowUserAccredit);

			foreach (string userName in usernames)
			{
				dc.UsersInRoles.AddUserToRole(userName, role.RoleId);
			}
		}

		/// <summary>
		/// 将指定的用户添加到指定的角色中。
		/// </summary>
		/// <param name="usernames">一个字符串数组，其中包含要添加到指定角色的用户名。</param>
		/// <param name="roleName">要将指定的用户名添加到的角色。</param>
		public static void AddUsersToRole(string[] usernames, int? siteId, string roleName)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			Role role = dc.Roles.GetItem(siteId, roleName);
			if (role == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			GetAccreditRight(dc, role, true);	// 权限验证

			AddUsersToRole(dc, usernames, role);
			dc.SubmitChanges();

			// 记录日志
			Logs.Insert(dc, ResourceId, (int)PermissionCode.Accredit, INFO_TYPE, roleName, PermissionCode.Accredit.ToString() + "/AddUsersToRole", Serialization.SerializeJson(usernames));
		}

		/// <summary>
		/// 将指定的用户添加到指定的角色中。
		/// </summary>
		/// <param name="usernames">一个字符串数组，其中包含要添加到指定角色的用户名。</param>
		/// <param name="roleId">要将指定的用户名添加到的角色。</param>
		public static void AddUsersToRole(string[] usernames, Guid roleId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			Role role = dc.Roles.GetItem(roleId);
			if (role == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			GetAccreditRight(dc, role, true);	// 权限验证

			AddUsersToRole(dc, usernames, role);
			dc.SubmitChanges();

			// 记录日志
			Logs.Insert(dc, ResourceId, (int)PermissionCode.Accredit, INFO_TYPE, role.RoleId.ToString(), PermissionCode.Accredit.ToString() + "/AddUsersToRole", Serialization.SerializeJson(usernames));
		}
		#endregion



		#region RemoveUsersFromRole
		/// <summary>
		/// 从角色中移除指定的用户。
		/// </summary>
		/// <param name="usersNames">移除的用户列表。</param>
		/// <param name="siteId">角色所属的站点。</param>
		/// <param name="roleName">操作的角色。</param>
		public static void RemoveUsersFromRole(string[] usersNames, int? siteId, string roleName)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			Role role = dc.Roles.GetItem(siteId, roleName);
			if (role == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			if (Roles.RolePropertyHasProperty(role.PropertyCode, RolePropertyCode.DisallowUserAccredit))
				throw new OperationException(Res.Roles_DisallowUserAccredit);

			GetAccreditRight(dc, role, true);	// 权限验证

			dc.UsersInRoles.RemoveUsersFromRole(usersNames, role.RoleId);
			dc.SubmitChanges();

			// 记录日志
			Logs.Insert(dc, ResourceId, (int)PermissionCode.Accredit, INFO_TYPE, roleName, PermissionCode.Accredit.ToString() + "/RemoveUsersFromRole", Serialization.SerializeJson(usersNames));
		}

		/// <summary>
		/// 从角色中移除指定的用户。
		/// </summary>
		/// <param name="usersNames">移除的用户列表。</param>
		/// <param name="roleId">角色的标识。</param>
		public static void RemoveUsersFromRole(string[] usersNames, Guid roleId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			Role role = dc.Roles.GetItem(roleId);
			if (role == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			if (Roles.RolePropertyHasProperty(role.PropertyCode, RolePropertyCode.DisallowUserAccredit))
				throw new OperationException(Res.Roles_DisallowUserAccredit);

			GetAccreditRight(dc, role, true);	// 权限验证

			dc.UsersInRoles.RemoveUsersFromRole(usersNames, role.RoleId);
			dc.SubmitChanges();

			// 记录日志
			Logs.Insert(dc, ResourceId, (int)PermissionCode.Accredit, INFO_TYPE, role.RoleId.ToString(), PermissionCode.Accredit.ToString() + "/RemoveUsersFromRole", Serialization.SerializeJson(usersNames));
		}
		#endregion



		#region SetRoleUsers
		/// <summary>
		/// 设置角色包含的用户。
		/// </summary>
		/// <param name="roleName">角色名。</param>
		/// <param name="usernames">角色所包含的用户。</param>
		public static void SetRoleUsers(int? siteId, string roleName, string[] usernames)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			Role role = dc.Roles.GetItem(siteId, roleName);
			if (role == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			if (Roles.RolePropertyHasProperty(role.PropertyCode, RolePropertyCode.DisallowUserAccredit))
				throw new OperationException(Res.Roles_DisallowUserAccredit);

			GetAccreditRight(dc, role, true);	// 权限验证

			string[] oUserNames = dc.ViewUsersInRoles.GetUsersInRole(siteId, roleName);
			if (oUserNames != null && oUserNames.Length > 0)
			{
				dc.UsersInRoles.RemoveUsersFromRole(oUserNames, role.RoleId);
				dc.SubmitChanges();
			}
			AddUsersToRole(dc, usernames, role);
			dc.SubmitChanges();

			// 记录日志
			Logs.Insert(dc, ResourceId, (int)PermissionCode.Accredit, INFO_TYPE, roleName, PermissionCode.Accredit.ToString() + "/SetRoleUsers", Serialization.SerializeJson(usernames));
		}

		/// <summary>
		/// 设置角色包含的用户。
		/// </summary>
		/// <param name="roleName">角色名。</param>
		/// <param name="usernames">角色所包含的用户。</param>
		public static void SetRoleUsers(Guid roleId, string[] usernames)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			Role role = dc.Roles.GetItem(roleId);
			if (role == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			if (Roles.RolePropertyHasProperty(role.PropertyCode, RolePropertyCode.DisallowUserAccredit))
				throw new OperationException(Res.Roles_DisallowUserAccredit);

			GetAccreditRight(dc, role, true);	// 权限验证

			string[] oUserNames = dc.ViewUsersInRoles.GetUsersInRole(roleId);
			if (oUserNames != null && oUserNames.Length > 0)
			{
				dc.UsersInRoles.RemoveUsersFromRole(oUserNames, role.RoleId);
				dc.SubmitChanges();
			}
			AddUsersToRole(dc, usernames, role);
			dc.SubmitChanges();

			// 记录日志
			Logs.Insert(dc, ResourceId, (int)PermissionCode.Accredit, INFO_TYPE, role.RoleId.ToString(), PermissionCode.Accredit.ToString() + "/SetRoleUsers", Serialization.SerializeJson(usernames));
		}
		#endregion



		#region SetRolePermissionState
		/// <summary>
		/// 获取角色权限列表。
		/// </summary>
		/// <param name="roleName">获取的角色名。</param>
		/// <returns>角色的权限列表。</returns>
		public static List<PermissionState> GetRolePermissions(Guid roleId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			
			return (from p in dc.RoleContainPermissions where p.RoleId == roleId select new PermissionState { ResourceId = p.ResourceId, PermissionCode = p.PermissionCode, IsEnabled = p.IsEnabled }).ToList();
		}

		/// <summary>
		/// 获取角色的指定类别的权限。
		/// </summary>
		/// <param name="roleName">获取的角色名。</param>
		/// <param name="categoryId">指定的类别标识。</param>
		/// <returns>角色的指定类别的权限。</returns>
		public static List<PermissionState> GetRolePermissions(Guid roleId, Guid categoryId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			return (from p in dc.RoleContainPermissions where p.RoleId == roleId
					&& (from p1 in dc.Resources where p1.CategoryId == categoryId select p1.ResourceId).Contains(p.ResourceId)
					select new PermissionState { ResourceId = p.ResourceId, PermissionCode = p.PermissionCode, IsEnabled = p.IsEnabled }).ToList();
		}

		/// <summary>
		/// 获取角色的指定资源的权限。
		/// </summary>
		/// <param name="roleName">获取的角色名。</param>
		/// <param name="resourceIds">指定的资源标识列表。</param>
		/// <returns>角色的指定资源的权限。</returns>
		public static List<PermissionState> GetRolePermissions(Guid roleId, IEnumerable<Guid> resourceIds)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			return (from p in dc.RoleContainPermissions
					where p.RoleId == roleId
						&& resourceIds.Contains(p.ResourceId)
					select new PermissionState { ResourceId = p.ResourceId, PermissionCode = p.PermissionCode, IsEnabled = p.IsEnabled }).ToList();
		}

		/// <summary>
		/// 设置角色权限。
		/// </summary>
		/// <param name="roleName">设置的角色。</param>
		/// <param name="states">角色的状态。</param>
		private static void SetRolePermissions(Guid roleId, IEnumerable<PermissionState> states, bool isValidate)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			Role role = dc.Roles.GetItem(roleId);
			if (role == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			if (Roles.RolePropertyHasProperty(role.PropertyCode, RolePropertyCode.DisallowRoleAccredit))
				throw new OperationException(Res.Roles_DisallowRoleAccredit);

			if (isValidate) GetAccreditRight(dc, role, true);	// 权限验证

			foreach (PermissionState state in states)
			{
				RoleContainPermission rState = dc.RoleContainPermissions.GetItem(role.RoleId, state.ResourceId, state.PermissionCode);
				if (rState == null)
				{
					rState = state.ToNewEntity<RoleContainPermission>();
					rState.RoleId = role.RoleId;
					dc.RoleContainPermissions.InsertOnSubmit(rState);
				}
				else
				{
					if (rState.IsEnabled == state.IsEnabled)
						continue;
					rState.IsEnabled = state.IsEnabled;
				}
			}

			dc.SubmitChanges();
		}

		/// <summary>
		/// 设置角色权限。
		/// </summary>
		/// <param name="roleName">设置的角色。</param>
		/// <param name="states">角色的状态。</param>
		internal static void _SetRolePermissions(Guid roleId, IEnumerable<PermissionState> states)
		{
			SetRolePermissions(roleId, states, false);
		}

		/// <summary>
		/// 设置角色权限。
		/// </summary>
		/// <param name="roleName">设置的角色。</param>
		/// <param name="states">角色的状态。</param>
		public static void SetRolePermissions(Guid roleId, IEnumerable<PermissionState> states)
		{
			SetRolePermissions(roleId, states, true);

			// 记录日志
			Logs.Insert(new GenericModuleDataContext(), ResourceId, (int)PermissionCode.Accredit, INFO_TYPE, roleId.ToString(), PermissionCode.Accredit.ToString() + "/SetRolePermissions", null);
		}
		#endregion



		#region Delete
		/// <summary>
		/// 删除角色。
		/// </summary>
		/// <param name="roleName">删除角色的名称。</param>
		public static void Delete(int? siteId, string roleName)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			Role role = dc.Roles.GetItem(siteId, roleName);
			if (role == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			if (Roles.RolePropertyHasProperty(role.PropertyCode, RolePropertyCode.DisallowDelete))
				throw new OperationException(Res.Roles_DisallowDelete);

			GetDeleteRight(dc, role, true);	// 权限验证

			Delete(dc, role);
			dc.SubmitChanges();

			// 记录日志
			Logs.Insert(dc, ResourceId, (int)PermissionCode.Delete, INFO_TYPE, roleName, PermissionCode.Delete.ToString(), null);
		}

		/// <summary>
		/// 删除角色。
		/// </summary>
		/// <param name="roleId">删除的角色标识。</param>
		public static void Delete(Guid roleId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			Role role = dc.Roles.GetItem(roleId);
			if (role == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			if (Roles.RolePropertyHasProperty(role.PropertyCode, RolePropertyCode.DisallowDelete))
				throw new OperationException(Res.Roles_DisallowDelete);

			GetDeleteRight(dc, role, true);	// 权限验证

			Delete(dc, role);
			dc.SubmitChanges();

			// 记录日志
			Logs.Insert(dc, ResourceId, (int)PermissionCode.Delete, INFO_TYPE, role.RoleId.ToString(), PermissionCode.Delete.ToString(), null);
		}

		#region internal Delete
		internal static void Delete(GenericModuleDataContext dc, Role role)
		{
			RoleContainPermissions.DeleteByParent(dc, role);	// 删除关联数据
			dc.Roles.DeleteOnSubmit(role);
		}
		#endregion
		#endregion
	}



	/// <summary>
	/// Roles 类对应操作权限部分。（受限站点资源。）
	/// </summary>
	public static partial class Roles
	{
		#region GetCreateRight
		/// <summary>
		/// 获取当前用户是否有创建角色的权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="role">创建的角色。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有创建角色的权限。</returns>
		public static bool GetCreateRight(GenericModuleDataContext dc, Role role, bool triggerException)
		{
			string userName = Users.CurrentUserName;
			int permissionCode = (int)PermissionCode.Create;
			bool b = dc.AccessController.GetUserIsHasPermission<Role>(userName, role, ResourceId, permissionCode, role.SiteId);

			if (triggerException && !b)
				throw new PermissionException(userName, role, ResourceId, permissionCode, Res.PermissionExceptionMessage);
			return b;
		}

		/// <summary>
		/// 获取当前用户是否有创建角色的权限。
		/// </summary>
		/// <param name="role">创建的角色。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有创建角色的权限。</returns>
		public static bool GetCreateRight(Role role, bool triggerException)
		{
			return GetCreateRight(new GenericModuleDataContext(), role, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有创建角色的权限。
		/// </summary>
		/// <param name="role">创建的角色。</param>
		/// <returns>布尔值表示当前用户是否有创建角色的权限。</returns>
		public static bool GetCreateRight(Role role)
		{
			return GetCreateRight(role, false);
		}
		#endregion



		#region GetAccreditRight
		/// <summary>
		/// 获取当前用户是否有指定角色的用户授权权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="role">进行用户授权操作的角色信息。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有指定角色的用户授权权限。</returns>
		public static bool GetAccreditRight(GenericModuleDataContext dc, Role role, bool triggerException)
		{
			string userName = Users.CurrentUserName;
			int permissionCode = (int)PermissionCode.Create;
			bool b = dc.AccessController.GetUserIsHasPermission<Role>(userName, role, ResourceId, permissionCode, role.SiteId);

			if (triggerException && !b)
				throw new PermissionException(userName, role, ResourceId, permissionCode, Res.PermissionExceptionMessage);
			return b;
		}

		/// <summary>
		/// 获取当前用户是否有指定角色的用户授权权限。
		/// </summary>
		/// <param name="role">进行用户授权操作的角色信息。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有指定角色的用户授权权限。</returns>
		public static bool GetAccreditRight(Role role, bool triggerException)
		{
			return GetAccreditRight(new GenericModuleDataContext(), role, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有指定角色的用户授权权限。
		/// </summary>
		/// <param name="role">进行用户授权操作的角色信息。</param>
		/// <returns>布尔值表示当前用户是否有指定角色的用户授权权限。</returns>
		public static bool GetAccreditRight(Role role)
		{
			return GetAccreditRight(role, false);
		}

		/// <summary>
		/// 获取当前用户是否有指定角色的用户授权权限。
		/// </summary>
		/// <param name="dc"></param>
		/// <param name="role"></param>
		/// <param name="triggerException"></param>
		/// <param name="siteId"></param>
		/// <returns></returns>
		public static bool GetAccreditRight(GenericModuleDataContext dc, Role role, bool triggerException,int? siteId)
		{
			string userName = Users.CurrentUserName;
			int permissionCode = (int)PermissionCode.Create;
			bool b = dc.AccessController.GetUserIsHasPermission<Role>(userName, role, ResourceId, permissionCode, siteId);

			if (triggerException && !b)
				throw new PermissionException(userName, role, ResourceId, permissionCode, Res.PermissionExceptionMessage);
			return b;
		}
		/// <summary>
		/// 获取当前用户是否有指定角色的用户授权权限。
		/// </summary>
		/// <param name="role"></param>
		/// <param name="triggerException"></param>
		/// <param name="siteId"></param>
		/// <returns></returns>
		public static bool GetAccreditRight(Role role, bool triggerException,int? siteId)
		{
			return GetAccreditRight(new GenericModuleDataContext(), role, triggerException, siteId);
		}
		/// <summary>
		/// 获取当前用户是否有指定角色的用户授权权限。
		/// </summary>
		/// <param name="role"></param>
		/// <param name="siteId"></param>
		/// <returns></returns>
		public static bool GetAccreditRight(Role role,int? siteId)
		{
			return GetAccreditRight(role, false, siteId);
		}





		#endregion



		#region GetDeleteRight
		/// <summary>
		/// 获取当前用户是否有指定角色的删除权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="role">进行用户删除操作的角色信息。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有指定角色的删除权限。</returns>
		public static bool GetDeleteRight(GenericModuleDataContext dc, Role role, bool triggerException)
		{
			string userName = Users.CurrentUserName;
			int permissionCode = (int)PermissionCode.Delete;
			bool b = dc.AccessController.GetUserIsHasPermission<Role>(userName, role, ResourceId, permissionCode, role.SiteId);

			if (triggerException && !b)
				throw new PermissionException(userName, role, ResourceId, permissionCode, Res.PermissionExceptionMessage);
			return b;
		}

		/// <summary>
		/// 获取当前用户是否有指定角色的删除权限。
		/// </summary>
		/// <param name="role">进行用户删除操作的角色信息。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有指定角色的删除权限。</returns>
		public static bool GetDeleteRight(Role role, bool triggerException)
		{
			return GetDeleteRight(new GenericModuleDataContext(), role, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有指定角色的删除权限。
		/// </summary>
		/// <param name="role">进行用户删除操作的角色信息。</param>
		/// <returns>布尔值表示当前用户是否有指定角色的删除权限。</returns>
		public static bool GetDeleteRight(Role role)
		{
			return GetDeleteRight(role, false);
		}
		#endregion
	}




	/// <summary>
	/// Roles 类后台管理部分。
	/// </summary>
	public static partial class Roles
	{
		public static bool GetManageListRight()
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			return dc.AccessController.GetUserIsHasPermission<object>(Users.CurrentUserName, null, Roles.ResourceId, (int)Roles.PermissionCode.Delete, App.Context.CurrentSiteId);
		}

		public static bool GetManageListRight(int? siteId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			return dc.AccessController.GetUserIsHasPermission<object>(Users.CurrentUserName, null, Roles.ResourceId, (int)Roles.PermissionCode.Delete, siteId);
		}



		public static PaginationInfo<List<Role>> GetPaginationManageList(int? siteId, string keyword, int pageSize, int currentPage)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			var q = from p in dc.Roles
					select p;

			if (siteId.HasValue)
				q = q.Where(p => p.SiteId == siteId.Value);
			if (!string.IsNullOrEmpty(keyword))
				q = q.Where(p => p.RoleName.Contains(keyword));

			PaginationInfo<List<Role>> pageInfo = new PaginationInfo<List<Role>>();
			pageInfo.PageSize = pageSize;
			pageInfo.CurrentPage = currentPage;
			pageInfo.RecordCount = q.Count();
			pageInfo.Records = q.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
			return pageInfo;
		}
		
		public static PaginationInfo<List<Role>> GetPaginationSelectorList(string keyword, Guid[] roleIds, RolePropertyCode? excludePropertyCode, Guid[] excludeRoleIds, int pageSize, int currentPage)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			var q = from p in dc.Roles
					select p;

			if (!string.IsNullOrEmpty(keyword))
				q = q.Where(p => p.RoleName.Contains(keyword));

			if (roleIds != null)
			{
				if (roleIds.Length > 0)
					q = q.Where(p => roleIds.Contains(p.RoleId));
				else
					q = q.Where(p => 1 == 0);
			}

			if (excludePropertyCode.HasValue)
				q = q.Where(p => (p.PropertyCode & (int)excludePropertyCode.Value) == 0);

			if (excludeRoleIds != null && excludeRoleIds.Length > 0)
				q = q.Where(p => !excludeRoleIds.Contains(p.RoleId));

			PaginationInfo<List<Role>> pageInfo = new PaginationInfo<List<Role>>();
			pageInfo.PageSize = pageSize;
			pageInfo.CurrentPage = currentPage;
			pageInfo.RecordCount = q.Count();
			pageInfo.Records = q.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
			return pageInfo;
		}

		public static List<Role> GetUserAccreditList(string userName)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			Guid[] roleIds = GetRolesForUser(userName);

			var q = from p in dc.Roles
					where roleIds.Contains(p.RoleId)
					select p;

			return q.ToList();
		}
	}
}